package com.ruoyi.pcj.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mashuai.utils.toolkit.core.msHandlebean.MsHandleDataUtils;
import com.mashuai.utils.toolkit.core.msValidation.annotation.MsCheckObjParams;
import com.mashuai.utils.toolkit.core.msValidation.annotation.MsCheckParams;
import com.ruoyi.basis.service.MsBaseServiceImpl;

import java.util.Date;
import java.util.List;

import com.mashuai.utils.toolkit.core.msMp.MsDb;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basis.utils.mp.MpConditionUtils;
import com.ruoyi.basis.utils.mp.MpPageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pcj.domain.PcjChatGroup;
import com.ruoyi.pcj.domain.PcjSysUser;
import net.sf.jsqlparser.util.validation.feature.MariaDbVersion;
import org.apache.commons.collections4.MapUtils;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.pcj.mapper.PcjChatGroupUserMapper;
import com.ruoyi.pcj.domain.PcjChatGroupUser;
import com.ruoyi.pcj.service.IPcjChatGroupUserService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 聊天室-人员Service业务层处理
 *
 * @author ms
 * @date 2024-02-29
 */
@Service
public class PcjChatGroupUserServiceImpl extends MsBaseServiceImpl<PcjChatGroupUserMapper, PcjChatGroupUser> implements IPcjChatGroupUserService {

    @Override
    public <E extends IPage<PcjChatGroupUser>> E page(E page, Wrapper<PcjChatGroupUser> qw) {
        return baseMapper.selectPage(page, qw);
    }

    /**
     * 查询聊天室-人员列表
     *
     * @param params 聊天室-查询参数 {"pageNum":1,"pageSize":10}
     * @return 聊天室-人员
     */
    @Override
    public IPage<PcjChatGroupUser> selectPcjChatGroupUserList(Map<String, Object> params) {
        //获取条件构造器
        QueryWrapper<PcjChatGroupUser> qw = MpConditionUtils.getQueryWrapper(params, PcjChatGroupUser.class);
        //分页查询
        Page<PcjChatGroupUser> page = this.page(MpPageUtils.getPage(params), qw);
        return page;
    }

    @MsCheckObjParams(keys = "groupId")
    @Override
    public IPage<PcjChatGroupUser> getData(Map<String, Object> params) {
        LambdaQueryWrapper<PcjChatGroupUser> qw = Wrappers.lambdaQuery();
        qw.eq(PcjChatGroupUser::getGroupId,MapUtils.getString(params,"groupId"));
        IPage<PcjChatGroupUser> page = MsDb.page(MpPageUtils.getPage(params), qw, PcjChatGroupUser.class);
        MsHandleDataUtils.handleTbOrDictValBeans(page.getRecords(),PcjChatGroupUser.class);
        return page;
    }

    @Override
    public List<PcjSysUser> getOnlineUsers(Map<String, Object> params) {
        String groupId = MapUtils.getString(params, "groupId");
        List<PcjChatGroupUser> pcjChatGroupUsers = getGroupUsersByGroupId(groupId);

        List<Long> list = pcjChatGroupUsers.stream().map(PcjChatGroupUser::getUserId).collect(Collectors.toList());
        LambdaQueryWrapper<PcjSysUser> qw2 = Wrappers.lambdaQuery();
        qw2.in(PcjSysUser::getUserId, list);
        List<PcjSysUser> userList = MsDb.list(qw2, PcjSysUser.class);
        return userList;
    }

    private List<PcjChatGroupUser> getGroupUsersByGroupId(String groupId) {
        LambdaQueryWrapper<PcjChatGroupUser> qw = Wrappers.lambdaQuery();
        qw.eq(PcjChatGroupUser::getGroupId, groupId);
        qw.eq(PcjChatGroupUser::getStatus, "0");
        return this.baseMapper.selectList(qw);
    }

    /**
     * 销毁房间
     * @param params
     * @return
     */
    @Override
    @Transactional
    public Boolean destroyRoom(Map<String, Object> params) {
        String groupId = MapUtils.getString(params, "groupId");
        // 更改房间中所有用户状态
        List<PcjChatGroupUser> pcjChatGroupUsers = getGroupUsersByGroupId(groupId);
        for (PcjChatGroupUser groupUser : pcjChatGroupUsers) {
            groupUser.setStatus("1");
            this.baseMapper.updateById(groupUser);
        }

        // 更改房间状态和结束时间
        LambdaQueryWrapper<PcjChatGroup> qw = Wrappers.lambdaQuery();
        qw.eq(PcjChatGroup::getId, groupId);
        PcjChatGroup pcjChatGroup = MsDb.getOne(qw, PcjChatGroup.class);
        pcjChatGroup.setStatus("1");
        pcjChatGroup.setEndTime(new Date());
        return MsDb.updateById(pcjChatGroup);
    }

    @Override
    public Boolean putBlackRoom(Map<String, Object> params) {
        String groupId = MapUtils.getString(params, "groupId");
        Long userId = MapUtils.getLong(params, "userId");
        PcjChatGroupUser groupUser = getGroupUser(groupId, userId);
        groupUser.setStatus("2");
        return MsDb.updateById(groupUser);
    }

    /**
    * @Author Jdike
    * @Description 获取当前房间在线用户
    * @Date 23:32 2024/3/28
    * @Param [groupId, userId]
    * @return com.ruoyi.pcj.domain.PcjChatGroupUser
    **/
    private PcjChatGroupUser getGroupUser(String groupId, Long userId) {
        LambdaQueryWrapper<PcjChatGroupUser> qw = Wrappers.lambdaQuery();
        qw.eq(PcjChatGroupUser::getGroupId, groupId);
        qw.eq(PcjChatGroupUser::getUserId, userId);
        qw.eq(PcjChatGroupUser::getStatus, "0");
        return this.baseMapper.selectOne(qw);
    }

    /**
     * 根据id查询聊天室-人员
     *
     * @param id 聊天室-人员主键
     * @return 聊天室-人员
     */
    @Override
    public PcjChatGroupUser selectPcjChatGroupUserById(String id) {
        //首先获取主表信息
        PcjChatGroupUser pcjChatGroupUser = MsDb.getById(id, PcjChatGroupUser.class);
        return pcjChatGroupUser;
    }

    /**
     * 回填子表信息
     **/

    /**
     * 新增聊天室-人员
     *
     * @param pcjChatGroupUser 聊天室-人员
     * @return 结果
     */
    @Override
    public Boolean insertPcjChatGroupUser(PcjChatGroupUser pcjChatGroupUser) {
        //插入主表
        Boolean success = this.insertData(pcjChatGroupUser);
        return success;
    }

    @Override
    @Transactional
    public Boolean savePcjChatUserInfo(Map<String, Object> params) {
        String groupId = MapUtils.getString(params, "groupId");
        String status = MapUtils.getString(params, "status");
        Long userId = SecurityUtils.getUserId();

        // 更新聊天室基本信息
        LambdaQueryWrapper<PcjChatGroup> qw = Wrappers.lambdaQuery();
        qw.eq(PcjChatGroup::getId, groupId);
        PcjChatGroup pcjChatGroup = MsDb.getOne(qw, PcjChatGroup.class);
        if ("0".equals(status)) {
            // 查询此用户是否被此房间拉黑过
            Boolean whiteFlag = inWhiteList(groupId, userId);
            if (!whiteFlag) {
                return false;
            }

            pcjChatGroup.setOnlieNum(pcjChatGroup.getOnlieNum() + 1);
            pcjChatGroup.setUserNum(pcjChatGroup.getUserNum() + 1);
            // 保存到聊天室-人员表
            PcjChatGroupUser groupUser = new PcjChatGroupUser();
            groupUser.setUserId(userId);
            groupUser.setGroupId(groupId);
            groupUser.setStatus(status);
            groupUser.setEntryTime(new Date());
            insertPcjChatGroupUser(groupUser);
        } else if ("1".equals(status)) {
            pcjChatGroup.setOnlieNum(pcjChatGroup.getOnlieNum() - 1);
            // 更新聊天室-人员表
            PcjChatGroupUser groupUser = getGroupUser(groupId,userId);
            groupUser.setStatus(status);
            this.baseMapper.updateById(groupUser);
        }
        return MsDb.updateById(pcjChatGroup);
    }

    private Boolean inWhiteList(String groupId, Long userId) {
        LambdaQueryWrapper<PcjChatGroupUser> qw = Wrappers.lambdaQuery();
        qw.eq(PcjChatGroupUser::getGroupId, groupId);
        qw.eq(PcjChatGroupUser::getStatus, "2");
        PcjChatGroupUser groupUser = this.baseMapper.selectOne(qw);
        return null == groupUser;
    }

    /**
     * 修改聊天室-人员
     *
     * @param pcjChatGroupUser 聊天室-人员
     * @return 结果
     */
    @Override
    public Boolean updatePcjChatGroupUser(PcjChatGroupUser pcjChatGroupUser) {
        //修改主表
        Boolean success = this.updateData(pcjChatGroupUser);
        return success;
    }

    /**
     * 批量删除聊天室-人员
     *
     * @param ids 需要删除的聊天室-人员主键
     * @return 结果
     */
    @Override
    public Boolean deletePcjChatGroupUserByIds(String[] ids) {

        //删除主表
        Boolean success = this.removeBatchByIds(Arrays.asList(ids));
        return success;
    }

    /**
     * 根据主表id，删除子表所有数据
     **/
    /**
     * 对外提供的设置默认字段值，id为空新增，不为空更新
     **/
    public void setEntityDefValAuto(PcjChatGroupUser pcjChatGroupUser) {
        this.setDefFieldVal(pcjChatGroupUser);
    }
}
